/***********************************************************************************************************************
 * ############################################# Application AdewebLite #############################################
 * AdewebLite Android est une application permettant de consulter des emplois du temps fournis par l'université UHP
 * avec ou sans connexion internet (informations gardées en mémoire à chaque synchronisation). Et utilisant la web
 * API ADE pour collecter les données.
 * @author Andrianjafintrimo Victor, Zanette Sébastien
 * 
 * Basée sur l'application du même nom, utilisant le flux RSS (données à traiter), de :
 * @author Schnell Michaël, Zanette Sébastien
 * **********************************************************************************************************************
 */

package ade.screen;

import ade.database.Database;
import ade.exception.AAAException;
import ade.main.R;
import ade.schedule.Schedule;
import ade.schedule.UpdateManager;
import greendroid.app.GDActivity;
import greendroid.widget.ActionBarItem;
import greendroid.widget.ActionBarItem.Type;
import java.text.SimpleDateFormat;
import java.util.Date;
import ade.screen.schedule.parameters.ParameterType;
import ade.screen.schedule.parameters.Parameters;
import ade.screen.schedule.parameters.ScheduleName;
import ade.screen.schedule.parameters.SchedulePeriod;
import ade.screen.schedule.parameters.ScheduleProjectId;
import ade.screen.schedule.parameters.ScheduleResource;
import ade.screen.schedule.parameters.ScheduleRessourceTitle;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

/**
 * Vue affichant le formulaire pour créer un emploi du temps.
 * @author Zanette Sébastien, @author Andrianjafintrimo Victor
 */
public class CreateScheduleScreen extends GDActivity {

	/**
         * ID de l'élément d'aide dans la barre d'action 
	 */
	private static final int ITEM_HELP     = 1 ;

	/**
         * Composant contenant les différents champs du formulaire.
	 */
	private LinearLayout fields ;

	/**
	 * Différents champs affichés dans le formulaire.
	 */
	protected Parameters params ;

	/**
	 * L'index d'insersion pour les nouvelles ressources.
	 */
	private int newResIndex ;

	/** 
	 * Initialise la vue.
         * 
         * @param savedInstanceState 
         */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		this.onCreate(savedInstanceState, "Ajout d'un emploi du temps") ;
	}// onCreate(Bundle)

	/**
	 * Initialise la vue avec le titre donné.
	 * 
	 * @param 	savedInstanceState
	 * 			If the activity is being re-initialized after previously being shut 
	 * 			down then this {@code Bundle} contains the data it most recently supplied
	 * 			in onSaveInstanceState(Bundle). Note: Otherwise it is null.
	 * 
	 * @param 	title
	 * 			title used for this view
	 */
	public void onCreate(Bundle savedInstanceState, String title) {
		super.onCreate(savedInstanceState) ;
		this.setTitle(title) ;
		this.initActionBar() ;
		this.init() ;
		this.initListeners();
	}// onCreate(Bundle, String)

	/**
	 * Ajoute la vue à la liste d'écouteur de {@code UpdateManager}.
	 */
	@Override
	protected void onStart() {
		super.onStart() ;
		//Mise en place synchro
                //TO DO
	}// onStart()

	/**
	 *  Supprime la vue de la liste d'écouteur de {@code UpdateManager}.
	 */
	@Override
	protected void onStop() {
		super.onStop() ;
		//Arreter la synchro
                //TO DO
	}// onStop()

	/**
	 * Initialise la barre d'action de la vue.
	 */
	private void initActionBar() {
		this.addActionBarItem(Type.Help, ITEM_HELP) ;
	}// initActionBar()

	/**
	 * Définition des actions des éléments de la barre d'action.
	 */
	@Override
	public boolean onHandleActionBarItemClick(ActionBarItem item, int position) {
		switch (item.getItemId()) {
                //les différentes options possible présentent sur la barre d'action
		case CreateScheduleScreen.ITEM_HELP :
			this.startActivity(new Intent(this, InfoTabActivity.class)) ;
			break ;

		default :
			return super.onHandleActionBarItemClick(item, position) ;
		}// switch

		return true ;
	}// onHandleActionBarItemClick(ActionBarItem, int)

	/**
         * Initialise les champs avec les valeurs données pour l'affichage graphique.
	 * 
	 * @param 	name
	 * 			Initial values for the schedule name
	 * 
	 * @param 	resources
	 * 			Initial values for the resources
	 * 
	 * @param 	period
	 * 			Initial value for the period
	 * 
	 * @param 	projectId
	 * 			Initial value for the selected project
	 */
	public void init(String name, String resources, String period, String projectId) {
		LayoutInflater inflater = LayoutInflater.from(this) ;
		// Initialzing the fields --------------------------------------------------
		this.params = new Parameters() ;
		this.params.add(new ScheduleName(inflater,name));
		this.params.add(new ScheduleRessourceTitle(inflater, this));
		this.newResIndex = 2 ;
		for(String ressource : resources.split("\\|")) {
			this.params.add(new ScheduleResource(inflater, ressource, this)) ;
			this.newResIndex++ ;
		}// for
		this.params.add(new SchedulePeriod(inflater, period));
		this.params.add(new ScheduleProjectId(inflater, projectId));

		// Building the view layout ------------------------------------------------
		LinearLayout ll = (LinearLayout) View.inflate(this, 
				R.layout.create_schedule_screen, null) ;
		this.fields = (LinearLayout) ll.findViewById(R.id.fields) ;
		this.fields.setOrientation(LinearLayout.VERTICAL) ;
		for(ParameterType param : this.params) {
			this.fields.addView(param.getView(null, null)) ;
		}// for

		this.setActionBarContentView(ll) ;
	}// init(String, String, String, String)

	/**
	 * Ajoute une nouvelle ressource à la vue.
	 */
	public void addResource () {
		LayoutInflater inflater = LayoutInflater.from(this) ;
		ParameterType newRes = new ScheduleResource(inflater, "", this) ;
		this.params.add(this.newResIndex, newRes) ;
		this.fields.addView(newRes.getView(null,  null), this.newResIndex) ;
		this.newResIndex++ ;
	}// addResource()

	/**
	 * Supprime un ressource de la vue.
	 * 
	 * @param 	removedView
	 * 			view which should well be removed
	 * 
	 * @param 	id
	 * 			id of the view which should be removed
	 * 
	 * @see		ScheduleResource
	 */
	public void removeResource (View removedView, int id) {
		this.fields.removeView(removedView) ;
		this.params.removeResource(id) ;
		this.newResIndex-- ;
	}// removeResource()

	/**
	 * Initialise la vue avec les valeurs par défaut.
	 */
	public void init() {
		this.init("", "", "", "") ;
	}// init()

	/**
         * Attache les écouteurs des boutons "enregistrer" et "annuler".
	 */
	protected void initListeners() {	
		final Button saveButton   = (Button) this.findViewById(R.id.saveSchedule) ;
		final Button boutonCancel = (Button) this.findViewById(R.id.cancelSchedule) ;
		saveButton.setOnClickListener(this.getSaveListener()) ;
		boutonCancel.setOnClickListener(new CancelListener(this)) ;
	}// initListeners()

	/**
         * Retourne la 1ere instance trouvée de {@code ParamaterType} avec l'ID donné.
	 * 
	 * @param 	id
	 * 			id of the search {@code ParameterType}
	 * 
	 * @return	First instance of {@code ParamaterType} found with the given id
	 */
	public ParameterType getById(String id) {
		return this.params.getById(id) ;
	}// getById(String)

	/**
	 * Retourne toutes les instances trouvées de {@code ParamaterType} avec l'ID donné.
	 * 
	 * @param 	id
	 * 			id of the search {@code ParameterType}
	 * 
	 * @return	Array containing all the instance of {@code ParamaterType} found 
	 * 			with the given id
	 */
	public Parameters getAllById(String id) {
		return this.params.getAllById(id) ;
	}// getAllById(String)

	/**
         * Retourne le composant graphique contenant les champs du formulaire.
	 * 
	 * @return	
	 */
	public LinearLayout getFields() {
		return this.fields ;
	}// getFields()

	/**
	 * OnClickListener pour le bouton "enregistrer".
	 * 
         *  <p>Retrouve la donnée depuis le formulaire et insère l'emploi du temps dans la base de données si possible.
	 * 
         * @author  Zanette Sébastien, Andrianjafintrimo Victor
	 */
	class SaveListener extends Object implements OnClickListener {

		/**
                 * Vue contenant le composant attaché à l'écouteur.
		 */
		protected CreateScheduleScreen container ;

		/**
		 * Constructeur. 
		 * 
		 * @param 	container
		 * 			View containing the component attached to this listener
		 */
		public SaveListener(CreateScheduleScreen container) {
			super() ;
			this.container = container ;
		}// SaveListener(CreateScheduleScreen)

		/**
                 * Définition des actions du clique sur le composant attaché.
		 * 
		 * @param	actualView
		 * 			view of the component who has received a click event
		 */
		public void onClick(View actualView) {
			// Retrieve form data
			String name       = this.container.getById(ScheduleName.FIELD_ID).getValue(this.container.getFields()).toString() ;
			String ressources = this.container.getScheduleResources() ;
                            StringBuilder studentNum = new StringBuilder("") ;
                            StringBuilder ressNum =new StringBuilder("") ;
                            //Séparation des ressources en numéros étudiant et numéros de ressources
                            for(String r : ressources.split("\\|")){
                                if(r.length() == 8){
                                  studentNum.append("|");
                                  studentNum.append(r);
                                }
                                else {
                                  ressNum.append("|");
                                  ressNum.append(r);                                 
                                }
                            }

			int period        = (Integer) this.container.getById(SchedulePeriod.FIELD_ID).getValue(this.container.getFields()) ;
			int projectId     = (Integer) this.container.getById(ScheduleProjectId.FIELD_ID).getValue(this.container.getFields()) ;
			String lastModif  = "null" ;
                        String studentNumber = studentNum.toString() ;
                        String ressNumber = ressNum.toString() ;
                        if (studentNumber.length()>0) {
                            studentNumber = studentNumber.substring(1);
                        }
                        if (ressNumber.length()>0) {
                            ressNumber = ressNumber.substring(1) ;
                        }
			int status        = 0 ;
			String created    = new SimpleDateFormat("yyyy/MM/dd HH:mm").format(new Date()) ;

			// Data testing and schedule creation
                        Schedule sc = new Schedule(projectId, name, ressNumber, period, lastModif, status, created, studentNumber);
                        Database db = new Database() ;
                    try {
                        sc.validate(db);
                        if(container.isNetworkAvailable()){
                                //si l'utilisateur a entré au moins un numéro étudiant
                            if(!sc.getStudentNum().equals("")) {
                                sc.setStudentNumList(); //on recupére le(s) numéro(s)
                            }
                            //recupération des cours associés à l'emploi du temps
                            sc.build();
                            //Mise à jour de l'icone
                            UpdateManager.getInstance().setScheduleStatus(name, UpdateManager.STATUS_UPDATED);
                            long resInsert = db.insertSchedule(sc);
                            db.setLastModifSchedule(sc.getName());
                            this.container.onBackPressed() ;
                        }
                    } catch (AAAException e) {
                        Toast.makeText(this.container, e.getMessage(), Toast.LENGTH_LONG).show();
                        UpdateManager.getInstance().setScheduleStatus(name, UpdateManager.STATUS_NOT_UPDATED, e);
                    }// try 
                       
                         //UpdateManager.getInstance().addQueue(sc.getName()) ;
                         
                        
		}// onClick(View) 

	}// class SaveListener

	/**
	 * OnClickListener pour le bouton "annuler".
	 * 
	 * <p>Retour à la vue précédente.
	 * 
	 * @author ZANETTE Sébastien
	 */
	class CancelListener implements OnClickListener {

		/**
		 * Vue contenant le composant attaché à l'écouteur.
		 */
		protected CreateScheduleScreen container ;

		/**
		 * Constructeur. 
		 * 
		 * @param 	container
		 * 			View containing the component attached to this listener
		 */
		public CancelListener(CreateScheduleScreen container) {
			super() ;
			this.container = container ;
		}// CancelListener(CreateScheduleScreen)

		/**
		 * Définition des action du clique sur le composant attaché.
		 * 
		 * @param	actualView
		 * 			view of the component who has received a click event
		 */
		public void onClick(View actuelView) {
			this.container.onBackPressed() ;
		}// onClick(View)
		
	}// class CancelListener

	/**
	 * Retourne une instance de {@code OnClickListener} pour l'enregistrement.
	 * 
	 * @return	instance de {@code OnClickListener} pour l'enregistrement
	 */
	protected OnClickListener getSaveListener() {
		return new SaveListener(this) ;
	}// getSaveListener()

	/**
         * Affiche les messages d'erreurs si un emploi du temps n'a pas été mis à jour.
         * 
         * @param args 
         */
	public void onUpdate(Object... args) {
                //TO DO
	}// onUpdate(Object...)
	
        /**
         * Construit une chaine de caractères contenant les ressources séparées par '|'.
         * @return les ressources séparées par '|'.
         */
	protected String getScheduleResources () {
            StringBuffer resString = new StringBuffer() ;
		for(int resId=2; resId < this.newResIndex; ++resId) {
			View resView = this.fields.getChildAt(resId) ;
			String value = (String) this.params.get(resId).getValue(resView) ;
			if (value.length() > 0) {
				resString.append("|") ;
				resString.append(value) ;
			}// if
		}// for
		if (resString.length() == 0) {
			return "" ;
		}// if
		return resString.substring(1) ;
	}// getResources()
    
        /**
         * Vérifie si l'appareil est connecté à Internet
         * @return vrai si l'appareil est connecté à Internet, faux sinon
         */   
    protected boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null;
    }
/*
    protected boolean isAdeWebReachable() {
        HttpURLConnection connection;
        int responseCode = 0;
        try {
            connection = (HttpURLConnection) new URL("http://adeweb.uhp-nancy.fr/jsp/webapi?function=connect&login=ade_uhp&password=edt_uhp").openConnection();

            connection.setRequestMethod("HEAD");
            responseCode = connection.getResponseCode();
            
        } catch (MalformedURLException ex) {
            Logger.getLogger(CreateScheduleScreen.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(CreateScheduleScreen.class.getName()).log(Level.SEVERE, null, ex);
        }
        return responseCode == 200;

    }
*/

}// class CreateScheduleScreen
